<?php

namespace App\Models;

use App\Models\ComModel;

class RbacModel extends ComModel
{

    public $tablename;
    private $categorys;
    public $config;

    public function __construct(...$param)
    {
        parent::__construct();
    }

    /***管理员***/
    private function _user_where(&$select, $param)
    {
        // 条件搜索
        if ($param) {
            // 关键字 + 自定义字段搜索
            if (isset($param['keyword']) && $param['keyword'] != '') {

                if ($param['id']) {
                    $select->where('id', (int) $param['id']);
                } elseif ($param['ids']) {
                    $select->whereIn('id', $param['ids']);
                }

                if (isset($param['title'])) {
                    $select->like('title', urldecode($param['title']));
                }
            }

            if (isset($param['username'])) {
                $select->like('username', urldecode($param['username']));
            }

            if (isset($param['day'])) {
                $select->like('day', urldecode($param['day']));
            }

            // 时间搜索
            if (isset($param['sdate']) && $param['sdate']) {
                $select->where('addtime BETWEEN ' . max((int) strtotime($param['sdate'] . ' 00:00:00'), 1) . ' AND ' . ($param['edate'] ? (int) strtotime($param['edate'] . ' 23:59:59') : SITE_TIME));
            } elseif (isset($param['edate']) && $param['edate']) {
                $select->where('addtime BETWEEN 1 AND ' . (int) strtotime($param['edate'] . ' 23:59:59'));
            }
        }
        return $param;
    }

    public function user_limit_page($page = 0, $size = 10, $total = 0, $param = [])
    {
        $page = max(1, (int) $page);
        $total = (int) $total;
        $param = esc($param);

        if ($size > 0 && !$total) {
            $select = $this->db->table('admin')->select('count(*) as total');
            $param = $this->_user_where($select, $param);
            $query = $select->get();
            if (!$query) {
                log_message('error', '数据查询失败：' . 'admin');
                return [[], $total, $param];
            }
            $data = $query->getRowArray();
            $total = (int) $data['total'];
            $param['total'] = $total;
            unset($select);
            if (!$total) {
                return [[], $total, $param];
            }
        }

        $select = $this->db->table('admin');
        $order = isset($param['order']) ? esc($param['order']) : '';
        $param = $this->_user_where($select, $param);
        $size > 0 && $select->limit($size, $size * ($page - 1));
        $query = $select->orderBy($order)->get();
        if (!$query) {
            log_message('error', '数据查询失败：' . 'admin');
            return [[], $total, $param];
        }
        $data = $query->getResultArray();
        if ($data) {
            foreach ($data as $k => $v) {
                $data[$k]['regtime_date'] = date('Y-m-d H:i:s', $v['regtime']);
            }
        }
        $param['order'] = $order;
        $param['total'] = $total;
        return [$data, $total, $param];
    }

    public function addUser($data)
    {
        if (!$data || !is_array($data)) {
            return ams_rt(1, '参数错误');
        }

        $data = esc($data);

        if (!$data['roleid']) {
            return ams_rt(1, '请选择角色');
        } elseif (!$data['username']) {
            return ams_rt(1, '请填写用户名');
        } elseif (!$data['password']) {
            return ams_rt(1, '请填写密码');
        } elseif ((isset($data['phone']) && $data['phone']) && !ams_isphone($data['phone'])) {
            return ams_rt(1, '请填写正确的手机号码');
        }

        $data['roleid'] = intval($data['roleid']);

        if ($data['email'] && !filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
            return ams_rt(1, '请填写正确的邮件');
        }

        $session = \Config\Services::session();
        $admin = $session->get('admin');
        if ((!$admin || $admin['roleid'] != 1 || $admin['uid'] != 1) && $data['roleid'] == 1) {
            return ams_rt(1, '您没有权限,请选择其它角色');
        }

        $role = $this->db->table('rbac_role')->select('id,name,status')->where('id', $data['roleid'])->get()->getRowArray();
        if (!$role) {
            return ams_rt(1, '角色不存在');
        } elseif (!$role['status']) {
            return ams_rt(1, '角色已禁用');
        }

        if ($this->db->table('user')->where('username', $data['username'])->countAllResults()) {
            return ams_rt(1, '用户名已存在');
        }

        $request = \Config\Services::request();

        $password = $salt = '';
        $ip = $request->getIPAddress();
        $salt = ams_salt();
        $password = md5(sha1($data['password']) . $salt . sha1($data['password']));

        $idata = [
            'username' => $data['username'],
            'name' => $data['name'] ?? '',
            'email' => $data['email'] ?? '',
            'password' => $password,
            'salt' => $salt,
            'phone' => $data['phone'] ?? '',
            'regip' => $ip,
            'regtime' => time(),
        ];

        $this->db->table('user')->insert($idata);
        $uid = $this->db->insertID();
        if ($uid) {
            $this->db->table('admin')->insert(['uid' => $uid, 'roleid' => $data['roleid']]);
            $id = $this->db->insertID();
            if ($id) {
                return ams_rt(0, '操作成功', $data);
            }
        }
        $msg = $this->db->error();
        return ams_rt(1, '操作失败:' . ($msg['message'] ?? ''));
    }

    public function editUser($uid, $data)
    {
        if (!$uid || !$data || !is_array($data)) {
            return ams_rt(1, '参数错误');
        }
        $uid = intval($uid);
        $data = esc($data);

        if (!$data['roleid']) {
            return ams_rt(1, '请选择角色');
        } elseif ((isset($data['phone']) && $data['phone']) && !ams_isphone($data['phone'])) {
            return ams_rt(1, '请填写正确的手机号码');
        }
        if ($data['email'] && !filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
            return ams_rt(1, '请填写正确的邮件');
        }

        $data['roleid'] = intval($data['roleid']);

        $session = \Config\Services::session();
        $admin = $session->get('admin');
        if ((!$admin || $admin['roleid'] != 1 || $admin['uid'] != 1) && $data['roleid'] == 1) {
            return ams_rt(1, '您没有权限,请选择其它角色');
        }
        $role = $this->db->table('rbac_role')->select('id,name,status')->where('id', $data['roleid'])->get()->getRowArray();
        if (!$role) {
            return ams_rt(1, '角色不存在');
        } elseif (!$role['status']) {
            return ams_rt(1, '角色已禁用');
        }

        $user = $this->db->table('admin')->where('uid', $uid)->get()->getRowArray();
        if (!$user) {
            return ams_rt(1, '用户不存在');
        }

        if ($this->db->table('user')->where('uid<>' . $uid)->where('username', $data['username'])->countAllResults()) {
            return ams_rt(1, '用户名已存在');
        }

        if (isset($data['name']) && $data['name']) {
            $udata['name'] = $data['name'];
        }

        if (isset($data['phone']) && $data['phone']) {
            $udata['phone'] = $data['phone'];
        }

        if (isset($data['email']) && $data['email']) {
            $udata['email'] = $data['email'];
        }

        if (isset($data['nickname']) && $data['nickname']) {
            $udata['nickname'] = $data['nickname'];
        }

        $password = $salt = '';
        if (isset($data['password']) && $data['password']) {
            $salt = $user['salt'];
            $password = md5(sha1($data['password']) . $salt . sha1($data['password']));
            $udata['password'] = $password;
        }

        $this->db->table('user')->where('uid', $uid)->update($udata);
        $this->db->table('admin')->where('uid', $uid)->update(['roleid' => $data['roleid']]);

        return ams_rt(0, '操作成功', $data);
    }

    public function delUser($uid)
    {
        $uid = intval($uid);
        if (!$uid) {
            return ams_rt(1, '参数错误');
        } elseif ($uid == 1) {
            return ams_rt(1, '创始人不能删除');
        }
        $session = \Config\Services::session();
        $admin = $session->get('admin');
        $data = $this->db->table('admin')->where('uid', $uid)->get()->getRowArray();
        if (!$data) {
            return ams_rt(0, '操作成功', $data);
        }

        if ((!$admin || $admin['roleid'] != 1) && $data['roleid'] == 1) {
            return ams_rt(1, '您没有权限');
        }

        $this->db->table('admin')->where('uid', $uid)->delete();
        if ($this->db->affectedRows()) {
            //删除登录
            $this->db->table('admin_login')->where('uid', $uid)->delete();
            $this->db->table('admin_oplog')->where('uid', $uid)->delete();

            return ams_rt(0, '操作成功', $data);
        }
        return ams_rt(1, '操作失败', $data);
    }

    public function getUser($uid)
    {
        if (!$uid) {
            return ams_rt(1, '参数错误');
        }
        $uid = intval($uid);
        $row = $this->db->table('admin')->where('admin.uid', $uid)->join('user', 'admin.uid = user.uid')->get()->getRowArray();
        if (!$row) {
            return ams_rt(1, '数据不存在');
        }
        return ams_rt(0, 'ok', $row);
    }

    /***角色***/
    public function addRole($data)
    {
        if (!$data || !isset($data['name']) || !$data['name']) {
            return ams_rt(1, '请填写角色名称');
        }

        $data = esc($data);

        $rt = $this->field_exitsts('rbac_role', 'name', $data['name']);
        if ($rt) {
            return ams_rt(1, '角色名称已存在');
        }

        $idata = [
            'name' => $data['name'],
            'description' => isset($data['description']) ? $data['description'] : '',
            'status' => 1,
        ];
        $this->db->table('rbac_role')->insert($idata);
        $id = $this->db->insertID();
        if ($id) {
            return ams_rt(0, '操作成功', $id);
        }
        $msg = $this->db->error();
        return ams_rt(1, '操作失败:' . ($msg['message'] ?? ''));
    }

    public function editRole($id, $data)
    {
        if (!$id || !$data || !isset($data['name']) || !$data['name']) {
            return ams_rt(1, '参数不正确');
        }

        $data = esc($data);

        $id = intval($id);
        $rt = $this->field_exitsts('rbac_role', 'name', $data['name'], $id);
        if ($rt) {
            return ams_rt(1, '名称已存在');
        }
        $idata = [
            'name' => $data['name'],
            'description' => isset($data['description']) ? $data['description'] : '',
            'status' => 1,
        ];
        $this->db->table('rbac_role')->where('id', $id)->update($idata);
        $id = $this->db->affectedRows();
        if ($id) {
            return ams_rt(0, '操作成功', $id);
        }
        $msg = $this->db->error();
        return ams_rt(1, '操作失败:' . ($msg['message'] ?? ''));
    }

    public function getRole($id)
    {
        if (!$id) {
            return ams_rt(1, '参数不正确');
        }

        $id = intval($id);
        $data = $this->db->table('rbac_role')->where('id', $id)->get()->getRowArray();
        if ($data) {
            $data['auth'] = $data['auth'] ? json_decode($data['auth']) : [];
            return ams_rt(0, 'ok', $data);
        }
        return ams_rt(1, '数据不存在');
    }

    public function getAllRole()
    {
        $rows = $this->db->table('rbac_role')->select('id,name')->where('status', 1)->get()->getResultArray();
        return ams_rt(0, 'ok', $rows);
    }

    public function switchRoleStatus($id, $value)
    {
        if (!$id) {
            return ams_rt(1, '参数错误');
        } elseif ($id == 1) {
            return ams_rt(1, '顶级管理不用设置');
        }
        $row = $this->db->table('rbac_role')->select('id,name,status')->where('id', $id)->get()->getRowArray();
        if (!$row) {
            return ams_rt(1, '数据不存在');
        }
        $this->db->table('rbac_role')->where('id', $id)->update(['status' => intval($value)]);
        return ams_rt(0, '操作成功', $row);
    }

    public function delRole($id)
    {
        if (!$id) {
            return ams_rt(1, '参数不正确');
        }
        $id = intval($id);
        if ($id == 1) {
            return ams_rt(1, '不允许删除');
        }
        $this->db->table('rbac_role')->where('id', $id)->delete();
        $id = $this->db->affectedRows();
        if ($id) {
            $this->db->table('admin')->where('roleid', $id)->delete();
            return ams_rt(0, '操作成功', $id);
        }
        $msg = $this->db->error();
        return ams_rt(1, '操作失败:' . ($msg['message'] ?? ''));
    }

    /**
     * @param $roleid //角色id
     * @param $ruleids //规则id数组
     */
    public function setRoleAuth($roleid, $ruleids)
    {
        $roleid = intval($roleid);
        if (!$roleid) {
            return ams_rt(1, '参数错误');
        } elseif (!is_array($ruleids)) {
            return ams_rt(1, '参数错误');
        }

        $session = \Config\Services::session();
        $admin = $session->get('admin');
        $role = $this->db->table('rbac_role')->get()->getResultArray();
        if (!$role) {
            return ams_rt(1, '角色不存在');
        } elseif ($roleid == 1) {
            return ams_rt(1, '顶级管理员不用设置');
        }
        $ids = [];
        foreach ($ruleids as $id) {
            $ids[] = $id;
        }
        $rows = $this->db->table('rbac_rule')->select('id,uri')->whereIn('id', $ids)->get()->getResultArray();
        foreach ($rows as $row) {
            if ($row['uri']) {
                $auth[] = $row['uri'];
            }
        }

        $auth = json_encode($auth);
        $this->db->table('rbac_role')->where('id', $roleid)->update(['auth' => $auth]);
//        echo $this->db->getLastQuery();die;
        return ams_rt(0, '操作成功');
    }

    private function _role_where(&$select, $param)
    {
        // 条件搜索
        if ($param) {
            // 关键字 + 自定义字段搜索
            if (isset($param['keyword']) && $param['keyword'] != '') {

                if ($param['id']) {
                    $select->where('id', (int) $$param['id']);
                } elseif ($param['ids']) {
                    $select->whereIn('id', $param['ids']);
                }

                if (isset($param['title'])) {
                    $select->like('title', urldecode($param['title']));
                }
            }

            if (isset($param['username'])) {
                $select->like('username', urldecode($param['username']));
            }

            if (isset($param['day'])) {
                $select->like('day', urldecode($param['day']));
            }

            // 时间搜索
            if (isset($param['sdate']) && $param['sdate']) {
                $select->where('addtime BETWEEN ' . max((int) strtotime($param['sdate'] . ' 00:00:00'), 1) . ' AND ' . ($param['edate'] ? (int) strtotime($param['edate'] . ' 23:59:59') : SITE_TIME));
            } elseif (isset($param['edate']) && $param['edate']) {
                $select->where('addtime BETWEEN 1 AND ' . (int) strtotime($param['edate'] . ' 23:59:59'));
            }
        }
        return $param;
    }

    public function role_limit_page($page = 0, $size = 10, $total = 0, $param = [])
    {

        $page = max(1, (int) $page);
        $total = (int) $total;

        unset($param['page']);
        if ($param) {
            $param = esc($param);
        }

        if ($size > 0 && !$total) {
            $select = $this->db->table('rbac_role')->select('count(*) as total');
            $param = $this->_role_where($select, $param);
            $query = $select->get();
            if (!$query) {
                log_message('error', '数据查询失败：' . 'rbac_role');
                return [[], $total, $param];
            }
            $data = $query->getRowArray();
            $total = (int) $data['total'];
            $param['total'] = $total;
            unset($select);
            if (!$total) {
                return [[], $total, $param];
            }
        }

        $select = $this->db->table('rbac_role');
        $order = isset($param['order']) ? esc($param['order']) : '';
        $param = $this->_role_where($select, $param);
        $size > 0 && $select->limit($size, $size * ($page - 1));
        $query = $select->orderBy($order)->get();
        if (!$query) {
            log_message('error', '数据查询失败：' . 'rbac_role');
            return [[], $total, $param];
        }
        $data = $query->getResultArray();
        $param['order'] = $order;
        $param['total'] = $total;

        return [$data, $total, $param];
    }

    /***规则***/
    public function iniRule($dirname = '')
    {
        $mark = '';
        if ($dirname) {
            $dirname = ams_safe_replace($dirname);
            if (is_file(APPSPATH . ucfirst($dirname) . '/Config/Rules.php')) {
                $rules = require APPSPATH . ucfirst($dirname) . '/Config/Rules.php';
            }
            $mark = 'app-' . strtolower($dirname);
        } else {
            if (is_file(WRITEPATH . 'install/rules.php')) {
                $rules = require WRITEPATH . 'install/rules.php';
            }
        }

        if (!$rules || !is_array($rules)) {
            return ams_rt(1, '无需操作');
        }

        $this->addInstallRule($rules, $mark);

        return ams_rt(0, '操作成功');
    }

    public function addInstallRule($data, $mark = '')
    {
        foreach ($data as $top) {

            if (!isset($top) || !is_array($top)) {
                continue;
            }

            $left = $top['child'];
            unset($top['child']);
            $top['mark'] = $mark;

            $rt = $this->addRule(0, $top);
            if ($rt['code']) {
                continue;
            }
            $topid = $rt['data'];

            if ($left) {

                foreach ($left as $item) {

                    $link = $item['child'] ?? [];
                    unset($item['child']);
                    $item['mark'] = $mark;
                    $rt = $this->addRule($topid, $item);
                    if ($rt['code']) {
                        continue;
                    }

                    $pid = $rt['data'];

                    if ($link) {
                        foreach ($link as $v) {
                            $v['mark'] = $mark;
                            $rt = $this->addRule($pid, $v);
                            if ($rt['code']) {
                                continue;
                            }
                        }

                    }

                }
            }
        }
    }

    //添加规则
    public function addRule($pid, $data)
    {
        if (!$data || !$data['name']) {
            return ams_rt(1, '参数不正确');
        }

        $data = esc($data);
        $pid = intval($pid);

        $parent = $this->db->table('rbac_rule')->select('id,pid')->where('id', $pid)->get()->getRowArray();
        if (isset($parent) && $parent['pid'] != 0) {
            return ams_rt(1, '参数不正确');
        } elseif ($parent && (!isset($data['uri']) || !$data['uri'])) {
            return ams_rt(1, '请填写URI');
        }

        if ($data['uri']) {
            $data['uri'] = trim($data['uri'], '/');
        }

        if ($this->db->table('rbac_rule')->where('name', $data['name'])->countAllResults()) {
            return ams_rt(1, '名称已存在');
        }

        if (isset($data['uri']) && $data['uri']) {
            $uri = explode('/', $data['uri']);
            if (!$data['uri'] || !is_array($uri) || $uri[0] != 'admin' || count($uri) != 3) {
                return ams_rt(1, '参数不正确');
            }
            if ($this->db->table('rbac_rule')->where('uri', $data['uri'])->countAllResults()) {
                return ams_rt(1, 'URI已存在');
            }
        }

        $idata = [
            'pid' => $pid,
            'name' => $data['name'],
            'uri' => $data['uri'],
            'mark' => $data['mark'] ?? '',
            'skip' => isset($data['skip']) ? intval($data['skip']) : 0,
        ];

        $this->db->table('rbac_rule')->insert($idata);
        $id = $this->db->insertId();
        if ($id) {
            return ams_rt(0, '操作成功', $id);
        }
        $msg = $this->db->error();
        return ams_rt(1, '操作失败:' . ($msg['message'] ?? ''));
    }

    public function delRuleByMark($mark = '')
    {
        if ($mark) {
            $mark = ams_clean_xss($mark);
            $this->db->table('rbac_rule')->where('mark', $mark)->delete();
        }
    }

    public function editRule($id, $data)
    {
        if (!$data || !$data['name'] || !$id) {
            return ams_rt(1, '参数不正确');
        }

        $data = esc($data);

        $id = intval($id);

        if ($data['uri']) {
            $data['uri'] = trim($data['uri'], '/');
        }

        $row = $this->getRule($id);
        if ($row['pid']) {
            $parent = $this->db->table('rbac_rule')->select('id,pid')->where('id', $row['pid'])->get()->getRowArray();
            if ($parent['pid'] != 0) {
                return ams_rt(1, '参数不正确');
            }
        }

        if (!$row) {
            return ams_rt(1, '数据不存在');
        }

        if ($this->db->table('rbac_rule')->where('id <> ' . $id)->where('name', $data['name'])->countAllResults()) {
            return ams_rt(1, '名称已存在');
        }

        if (isset($data['uri']) && $data['uri']) {
            $uri = explode('/', $data['uri']);
            if (!$data['uri'] || !is_array($uri) || $uri[0] != 'admin' || count($uri) < 3) {
                return ams_rt(1, 'URI不正确');
            }
            if ($this->db->table('rbac_rule')->where('id <> ' . $id)->where('uri', $data['uri'])->countAllResults()) {
                return ams_rt(1, 'URI已存在');
            }
        }

        $this->db->table('rbac_rule')->where('id', $id)->update($data);
        if ($this->db->affectedRows()) {
            return ams_rt(0, '操作成功', $id);
        }
        $msg = $this->db->error();
        return ams_rt(1, '操作失败:' . ($msg['message'] ?? ''));
    }

    public function getRule($id)
    {
        if (!$id) {
            return [];
        }
        $id = intval($id);
        $data = $this->db->table('rbac_rule')->where('id', $id)->get()->getRowArray();
        return $data;
    }

    public function delRule($id)
    {
        if (!$id) {
            return ams_rt(1, '参数不正确');
        }
        $id = intval($id);
        $row = $this->db->table('rbac_rule')->where('id', $id)->get()->getRowArray();
        $son = $this->db->table('rbac_rule')->select('id')->where('pid', $id)->get()->getResultArray();
        if ($son) {
            foreach ($son as $k => $v) {
                $ids[] = $v['id'];
            }
            $child = $this->db->table('rbac_rule')->select('id')->whereIn('pid', $ids)->get()->getResultArray();
            if ($child) {
                foreach ($son as $k1 => $v1) {
                    $ids[] = $v1['id'];
                }
            }
            $this->db->table('rbac_rule')->whereIn('id', $ids)->delete();
        }
        $this->db->table('rbac_rule')->where('id', $id)->delete();
        $num = $this->db->affectedRows();
        if ($num) {
            return ams_rt(0, '操作成功', $row);
        }
        $msg = $this->db->error();
        return ams_rt(1, '操作失败:' . ($msg['message'] ?? ''));
    }

    public function getParentRuleTree()
    {
        $data = $this->db->table('rbac_rule')->where('pid', 0)->get()->getResultArray();
        if ($data) {
            foreach ($data as $k => $v) {
                $son = $this->db->table('rbac_rule')->where('pid', $v['id'])->get()->getResultArray();
                if ($son) {
                    $data = array_merge($data, $son);
                }
            }
        }
        if ($data) {
            $tree = new \App\Libraries\Tree();
            $data = $tree->get($data);
        } else {
            $data = [];
        }

        return $data;
    }

    //获取上级
    public function getParents()
    {
        $data = $this->db->table('rbac_rule')->where('pid', 0)->get()->getResultArray();
        return $data;
    }

    public function getParentRule()
    {
        $data = $this->db->table('rbac_rule')->where('pid', 0)->get()->getResultArray();
        if ($data) {
            foreach ($data as $k => $v) {
                $son = $this->db->table('rbac_rule')->where('pid', $v['id'])->get()->getResultArray();
                if (!$son) {
                    $son = [];
                }
                $data[$k]['son'] = $son;
            }
        }
        return ams_rt(0, 'ok', $data);
    }

    public function getRuleSons($pid = 0)
    {
        $pid = intval($pid);
        $data = $this->db->table('rbac_rule')->where('pid', $pid)->get()->getResultArray();
        if (!$data) {
            $data = [];
        }
        return $data;
    }

    public function getAllRule()
    {
        $rows = $this->db->table('rbac_rule')->where('pid', 0)->get()->getResultArray();
        if ($rows) {
            foreach ($rows as $k => $v) {
                $data[$v['id']] = $v;
                $childs = $this->db->table('rbac_rule')->where('pid', $v['id'])->get()->getResultArray();
                if ($childs) {

                    foreach ($childs as $k1 => $v1) {
                        $son = $this->db->table('rbac_rule')->where('pid', $v1['id'])->get()->getResultArray();
                        if (!$son) {
                            $son = [];
                        }
                        $v1['child'] = $son;

                        $data[$v['id']]['child'][$v1['id']] = $v1;
                    }

                } else {
                    $data[$v['id']]['child'] = [];
                }
            }
        } else {
            $data = [];
        }
        return $data;
    }

    private function _rule_where(&$select, $param)
    {
        // 条件搜索
        if ($param) {
            if (isset($param['name'])) {
                $select->like('name', urldecode($param['name']));
            }

            if (isset($param['pid']) && intval($param['pid'])) {
                $select->where('pid', intval($param['pid']));
            }
        }
        return $param;
    }

    public function rule_limit_page($page = 0, $size = 10, $total = 0, $param = [])
    {
        $page = max(1, (int) $page);
        $total = (int) $total;
        unset($param['page']);
        if ($param) {
            $param = esc($param);
        }
        if ($size > 0 && !$total) {
            $select = $this->db->table('rbac_rule')->select('count(*) as total');
            $param = $this->_rule_where($select, $param);
            $query = $select->get();
            if (!$query) {
                log_message('error', '数据查询失败：' . 'rbac_rule');
                return [[], $total, $param];
            }
            $data = $query->getRowArray();

            if (isset($param['pid']) && $param['pid']) {
                $total = 1;
            } else {
                $total = $this->getRuleParentTotal();
            }

            $param['total'] = $total;
            unset($select);

            if (isset($param['pid']) && intval($param['pid'])) {
                $data = $this->getRuleLine($param['pid']);
                unset($data['total']);
                // $param['total'] = $total = count($data);
            } else {
                $pid = $this->getRuleFisrtParentid($page);
                $data = $this->getRuleLine($pid);
            }

            if ($data) {
                $tree = new \App\Libraries\Tree();
                $data = $tree->get($data);
                return [$data, $total, $param];
            }

            if (!$total) {
                return [[], $total, $param];
            }
        }

        $select = $this->db->table('rbac_rule');
        $param = $this->_rule_where($select, $param);
        $size > 0 && $select->limit($size, $size * ($page - 1));
        $query = $select->orderBy('id', 'asc')->get();
        if (!$query) {
            log_message('error', '数据查询失败：' . 'rbac_rule');
            return [[], $total, $param];
        }
        $data = $query->getResultArray();

        if (isset($param['pid']) && intval($param['pid'])) {
            $data = $this->getRuleLine($param['pid']);
        } else {
            $pid = $this->getRuleFisrtParentid($page);
            $data = $this->getRuleLine($pid);
        }

        $total = $this->getRuleParentTotal();

        $param['total'] = $total;
        if ($data) {
            $tree = new \App\Libraries\Tree();
            $data = $tree->get($data);
        }
        return [$data, $total, $param];
    }

    public function getRuleFisrtParentid($page = 1)
    {
        $page = max(1, (int) $page);
        $pid = 0;
        $rows = $this->db->table('rbac_rule')->select('id')->where('pid', 0)->orderBy('id', 'ASC')->get()->getResultArray();
        if (!$rows) {
            $pid = 0;
        } else {
            $page = $page - 1;
            $pid = $rows[$page]['id'];
        }
        return $pid;
    }

    public function getRuleLine($id)
    {
        $data = [];
        $id = intval($id);
        $row = $this->db->table('rbac_rule')->where('id', $id)->get()->getRowArray();
        if (!$row) {
            return [];
        }

        //顶级
        if ($row['pid'] == 0) {
            $data[] = $row;
            $rows = $this->db->table('rbac_rule')->where('pid', $id)->get()->getResultArray();
            if ($rows) {
                foreach ($rows as $v1) {
                    $data[] = $v1;
                    $child = $this->db->table('rbac_rule')->where('pid', $v1['id'])->get()->getResultArray();
                    if ($child) {
                        foreach ($child as $v2) {
                            $data[] = $v2;
                        }
                    }
                }
            }
        } else {

            $data[] = $row;
            //查找它的上级
            $parent = $this->db->table('rbac_rule')->where('id', $row['pid'])->get()->getRowArray();
            if ($parent) {
                $data[] = $parent;
            }
            //查找它的下级
            $child = $this->db->table('rbac_rule')->where('pid', $row['id'])->get()->getResultArray();
            if ($child) {
                foreach ($child as $v2) {
                    $data[] = $v2;
                }
            }
        }

        return $data;
    }

    public function getRuleParentTotal()
    {
        $total = $this->db->table('rbac_rule')->where('pid', 0)->countAllResults();
        return $total;
    }

    public function getRoleAuth($user = [])
    {
        if (!$user || !$user['roleid']) {
            return false;
        }
        $role = $this->db->table('rbac_role')->where('id', $user['roleid'])->get()->getRowArray();
        if (!$role) {
            return false;
        }
        $auth = $role['auth'] ? json_decode($role['auth']) : [];
        return $auth;
    }

    public function checkAuth($user = [])
    {
        if (!$user || !$user['roleid']) {
            return false;
        }
        $role = $this->db->table('rbac_role')->where('id', $user['roleid'])->get()->getRowArray();
        if (!$role) {
            return false;
        }
        $auth = $role['auth'] ? json_decode($role['auth']) : [];

    }

}
